Skip to content

docs: note unpublished-port filter vs pre-netfilter DNAT - #25760

Merged
dvdksn merged 4 commits into
docker:mainfrom
locker95:docs/raw-prerouting-cni-note
Aug 12, 2026
Merged

docs: note unpublished-port filter vs pre-netfilter DNAT#25760
dvdksn merged 4 commits into
docker:mainfrom
locker95:docs/raw-prerouting-cni-note

Conversation

@locker95

Copy link
Copy Markdown
Contributor

When something else (e.g. a CNI) rewrites packets to a container IP before host netfilter, Docker's unpublished-port protection still applies. DOCKER-USER never sees that as "published" traffic.

Added a short note under the iptables DOCKER-USER section pointing at port publishing / nat-unprotected.

Fixes #25676

Explain that DOCKER-USER cannot re-open unpublished container ports
when another datapath already rewrites packets to those addresses.

Signed-off-by: Dean Chen <862469039@qq.com>
@locker95
locker95 requested a review from dvdksn as a code owner August 10, 2026 20:48
@netlify

netlify Bot commented Aug 10, 2026

Copy link
Copy Markdown

Deploy Preview for docsdocker ready!

Name Link
🔨 Latest commit b5d586e
🔍 Latest deploy log https://app.netlify.com/projects/docsdocker/deploys/6a7ca602b7f96a00080d9f24
😎 Deploy Preview https://deploy-preview-25760--docsdocker.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added area/engine Issue affects Docker engine/daemon area/networking Relates to anything around networking labels Aug 10, 2026
Signed-off-by: Dean Chen <862469039@qq.com>
@locker95

Copy link
Copy Markdown
Contributor Author

vale didn't like "datapath" — split it to "data path".

@robmry robmry left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @locker95, I agree it's worth a note here.

But for most readers, we'll probably need to say what "direct routing" is. With the CNI example, it sounds quite complicated at the moment. It'd probably also be better to link to the section on how to use the gateway_mode options, unfortunately they're not easy to guess.

How about something like ...

  > [!NOTE]
  >
  > By default, remote hosts can only reach a container through a port published
  > to one of the Docker host's addresses. Sending packets to the container's own
  > IP address instead ("direct routed" access) is not allowed.
  >
  > These packets are dropped by a rule in the `raw` table's `PREROUTING` chain,
  > which is processed before the `filter` table. So, they never reach the
  > `DOCKER-USER` chain, and a rule in `DOCKER-USER` cannot allow them.
  >
  > Any packet that reaches the host's firewall rules already addressed to a
  > container is treated this way. For example, a Kubernetes CNI plugin may
  > translate a Service address to a container address before the packet reaches
  > the host's `PREROUTING` rules. Docker cannot distinguish the result from a
  > packet routed to the container by a remote host. Which host interface these
  > packets arrive on depends on the plugin's data path — for an overlay network
  > it is normally the tunnel device.
  >
  > To allow direct routed access to a container's *published* ports, use network
  > option `com.docker.network.bridge.trusted_host_interfaces`, or daemon option
  > `allow-direct-routing`. Unpublished ports are still protected. See
  > [Direct routing to containers in bridge networks](./port-publishing.md#direct-routing-to-containers-in-bridge-networks).
  > To allow direct routed access to all container ports, published or not, see
  > [Gateway modes](./port-publishing.md#gateway-modes).

And, something similar for nftables (firewall-nftables.md, end of "Migrating ACCEPT rules") ...

  > [!NOTE]
  >
  > By default, remote hosts can only reach a container through a port published
  > to one of the Docker host's addresses. Sending packets to the container's own
  > IP address instead ("direct routed" access) is not allowed.
  >
  > These packets are dropped by a rule in the `raw-PREROUTING` chain of the
  > `docker-bridges` tables. Because a drop is final, a rule in one of your own
  > tables cannot allow them. And, because that chain runs at the `prerouting`
  > hook, before Docker's `filter-FORWARD` rules, a firewall mark added with
  > `--bridge-accept-fwmark` has no effect on it.
  >
  > Any packet that reaches the host's firewall rules already addressed to a
  > container is treated this way. For example, a Kubernetes CNI plugin may
  > translate a Service address to a container address before the packet reaches
  > the host's prerouting rules. Docker cannot distinguish the result from a
  > packet routed to the container by a remote host. Which host interface these
  > packets arrive on depends on the plugin's data path — for an overlay network
  > it is normally the tunnel device.
  >
  > To allow direct routed access to a container's *published* ports, use network
  > option `com.docker.network.bridge.trusted_host_interfaces`, or daemon option
  > `allow-direct-routing`. Unpublished ports are still protected. See
  > [Direct routing to containers in bridge networks](./port-publishing.md#direct-routing-to-containers-in-bridge-networks).
  > To allow direct routed access to all container ports, published or not, see
  > [Gateway modes](./port-publishing.md#gateway-modes).

Rewrite the note in plain language (what direct routing is, why raw
PREROUTING wins over DOCKER-USER) and mirror it for nftables. Point at
trusted_host_interfaces / allow-direct-routing and the gateway_mode docs.

Signed-off-by: Dean Chen <862469039@qq.com>
@locker95

Copy link
Copy Markdown
Contributor Author

good call — rewrote the note along those lines and added the matching one on the nftables page (raw-PREROUTING / fwmark won't help). linked the direct-routing + gateway_mode sections too.

Signed-off-by: Dean Chen <862469039@qq.com>

@robmry robmry left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thank you.

(We'll need a review from @dvdksn too.)

@dvdksn
dvdksn merged commit c8c1ada into docker:main Aug 12, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/engine Issue affects Docker engine/daemon area/networking Relates to anything around networking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document interaction: raw/PREROUTING protection for unpublished containers vs a CNI that translates Service VIPs before netfilter

3 participants